#include "md5.h"
#include <fstream>
#include <sstream>
#include <iomanip>
#include <openssl/evp.h>

namespace FileScanner {

std::string calculateMD5(const std::string& filePath) {
    std::ifstream file(filePath, std::ios::binary);
    if (!file.is_open()) {
        return "";
    }

    EVP_MD_CTX* mdContext = EVP_MD_CTX_new();
    if (!mdContext) {
        file.close();
        return "";
    }

    if (EVP_DigestInit_ex(mdContext, EVP_md5(), nullptr) != 1) {
        EVP_MD_CTX_free(mdContext);
        file.close();
        return "";
    }

    constexpr size_t BUFFER_SIZE = 8192;
    char buffer[BUFFER_SIZE];

    while (file.read(buffer, BUFFER_SIZE) || file.gcount() > 0) {
        if (EVP_DigestUpdate(mdContext, buffer, file.gcount()) != 1) {
            EVP_MD_CTX_free(mdContext);
            file.close();
            return "";
        }
    }

    file.close();

    unsigned char digest[EVP_MAX_MD_SIZE];
    unsigned int digestLength = 0;

    if (EVP_DigestFinal_ex(mdContext, digest, &digestLength) != 1) {
        EVP_MD_CTX_free(mdContext);
        return "";
    }

    EVP_MD_CTX_free(mdContext);

    std::ostringstream oss;
    for (unsigned int i = 0; i < digestLength; ++i) {
        oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(digest[i]);
    }

    return oss.str();
}

} // namespace FileScanner
